package com.atguigu.schedule.service.impl;

import com.atguigu.schedule.mapper.SecurityQuestionMapper;
import com.atguigu.schedule.mapper.SysUserMapper;
import com.atguigu.schedule.mapper.UserSecurityAnswerMapper;
import com.atguigu.schedule.pojo.*;
import com.atguigu.schedule.service.PasswordResetService;
import com.atguigu.schedule.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.SecureRandom;
import java.util.Base64;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class PasswordResetServiceImpl implements PasswordResetService {

    @Autowired
    private SecurityQuestionMapper securityQuestionMapper;
    
    @Autowired
    private UserSecurityAnswerMapper userSecurityAnswerMapper;
    
    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public List<SecurityQuestion> getAllActiveSecurityQuestions() {
        return securityQuestionMapper.selectByActive();
    }

    @Override
    public List<SecurityQuestion> getUserSecurityQuestions(String username) {
        SysUser user = sysUserMapper.selectByUsername(username);
        if (user == null) {
            return null;
        }
        
        List<UserSecurityAnswer> userAnswers = userSecurityAnswerMapper.selectByUserId(user.getUid());
        return userAnswers.stream()
                .map(answer -> securityQuestionMapper.selectById(answer.getQuestionId()))
                .filter(question -> question != null && question.getIsActive())
                .toList();
    }

    @Override
    public boolean verifySecurityAnswers(SecurityAnswersRequest request) {
        SysUser user = sysUserMapper.selectByUsername(request.getUsername());
        if (user == null) {
            return false;
        }
        
        List<UserSecurityAnswer> userAnswers = userSecurityAnswerMapper.selectByUserId(user.getUid());
        Map<String, String> providedAnswers = request.getAnswers();
        
        int correctAnswers = 0;
        for (UserSecurityAnswer userAnswer : userAnswers) {
            String questionId = userAnswer.getQuestionId().toString();
            String providedAnswer = providedAnswers.get(questionId);
            
            if (providedAnswer != null) {
                String hashedAnswer = MD5Util.encrypt(providedAnswer + userAnswer.getSalt());
                if (hashedAnswer.equals(userAnswer.getAnswerHash())) {
                    correctAnswers++;
                }
            }
        }
        
        // 至少需要回答2个问题
        return correctAnswers >= 2;
    }

    @Override
    public String resetPassword(PasswordResetRequest request) {
        // 验证安全问题答案
        SecurityAnswersRequest answersRequest = new SecurityAnswersRequest(request.getUsername(), request.getAnswers());
        if (!verifySecurityAnswers(answersRequest)) {
            return "安全问题答案验证失败";
        }
        
        // 验证密码强度
        if (!isPasswordStrong(request.getNewPassword())) {
            return "密码强度不够，必须包含大小写字母、数字、特殊字符，长度8-20位";
        }
        
        // 更新密码
        SysUser user = sysUserMapper.selectByUsername(request.getUsername());
        if (user == null) {
            return "用户不存在";
        }
        
        user.setUserPwd(MD5Util.encrypt(request.getNewPassword()));
        sysUserMapper.update(user);
        
        return "密码重置成功";
    }

    @Override
    public boolean setUserSecurityAnswers(Integer userId, List<SecurityQuestionRequest> securityQuestions) {
        if (securityQuestions == null || securityQuestions.size() < 2) {
            return false;
        }
        
        // 删除用户现有的安全问题答案
        userSecurityAnswerMapper.deleteByUserId(userId);
        
        // 添加新的安全问题答案
        for (SecurityQuestionRequest questionRequest : securityQuestions) {
            String salt = generateSalt();
            String hashedAnswer = MD5Util.encrypt(questionRequest.getAnswer() + salt);
            
            UserSecurityAnswer userAnswer = new UserSecurityAnswer();
            userAnswer.setUserId(userId);
            userAnswer.setQuestionId(questionRequest.getQuestionId());
            userAnswer.setAnswerHash(hashedAnswer);
            userAnswer.setSalt(salt);
            
            userSecurityAnswerMapper.insert(userAnswer);
        }
        
        return true;
    }
    
    private boolean isPasswordStrong(String password) {
        if (password == null || password.length() < 8 || password.length() > 20) {
            return false;
        }
        
        boolean hasUpperCase = password.chars().anyMatch(Character::isUpperCase);
        boolean hasLowerCase = password.chars().anyMatch(Character::isLowerCase);
        boolean hasDigit = password.chars().anyMatch(Character::isDigit);
        boolean hasSpecialChar = password.chars().anyMatch(ch -> "!@#$%^&*()_+-=[]{}|;:,.<>?".indexOf(ch) >= 0);
        
        return hasUpperCase && hasLowerCase && hasDigit && hasSpecialChar;
    }
    
    private String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16];
        random.nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }
}
